import os
import yt_dlp
from PyQt5.QtCore import QThread, pyqtSignal
from database import TaskDatabase
from task import Task
from utils import format_speed, format_size, sanitize_filename


class DownloadTask(QThread):
    progress_signal = pyqtSignal(int, str, str)
    finish_signal = pyqtSignal(Task)
    fail_signal = pyqtSignal(Task, str)
    total_downloaded = 0
    _last_downloaded = 0
    db = TaskDatabase()

    def get_task_id(self):
        return self.task.id

    def __init__(self, parent, task: Task):
        super().__init__(parent=parent)
        print('下载任务开始', task)
        self.task = task
        self._is_stopped = False
        self.max_retries = 3
        self.retry_count = 0
        self.save_path = task.path
        filename = sanitize_filename(self.task.title)
        self.ydl_opts = {
            'outtmpl': os.path.join(self.task.path, f'{filename}.mp4'),
            'format':  'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
            'merge_output_format': 'mp4',
            'quiet': True,
            'noplaylist': True,
            'progress_hooks': [self.progress_hook],
            'nocheckcertificate': True,
            'force_ipv4': True,
            'retries': 3,
            'http_headers': {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
                              '(KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
            },
            'cookiefile': 'cookies.txt',
        }

    def run(self):
        print('开始下载', self.task.url)
        while self.retry_count < self.max_retries:
            try:
                with yt_dlp.YoutubeDL(self.ydl_opts) as ydl:
                    ydl.download([self.task.url])
                return  # 成功后直接退出
            except Exception as e:
                self.retry_count += 1
                print(f"下载错误（第 {self.retry_count} 次）：{e}")
                if self.retry_count >= self.max_retries:
                    self.fail_signal.emit(self.task, "下载失败")
                    return

    def progress_hook(self, progress):
        try:
            if 'downloaded_bytes' in progress:
                downloaded = progress.get('downloaded_bytes', 0)
                if downloaded > self._last_downloaded:
                    delta_downloaded = downloaded - self._last_downloaded
                    self.total_downloaded += delta_downloaded
                self._last_downloaded = downloaded
                percent = int(progress.get('progress', 0) * 100) if 'progress' in progress else 0
                speed = progress.get('speed')
                self.progress_signal.emit(self.task.id, format_size(self.total_downloaded), format_speed(speed))
                self.db.update_progress(self.task.id, percent)
        except Exception as e:
            print(f'下载过程中发生错误:{progress}\n\n\n{str(e)}')
            self.fail_signal.emit(self.task, f'下载过程中发生错误:{progress}\n\n\n{str(e)}')

        if progress.get('status') == 'finished':
            self.db.finish_task(self.task.id)
            self._clean_temp_files()  # 清理临时文件
            self.finish_signal.emit(self.task)

    def stop(self):
        self._is_stopped = True
        self.terminate()

    def delete(self):
        try:
            print(f"Deleting task for URL: {self.task.url}")
            # 可在这里执行额外的清理操作
        except Exception as e:
            print(f"Error deleting task: {str(e)}")

    def _clean_temp_files(self):
        """清理当前任务相关的缓存文件（如 .part、.m4a）"""
        try:
            title = self.task.title
            for file in os.listdir(self.task.path):
                if file.startswith(title) and file.endswith(('.part', '.m4a', '.f*', '.webm')):
                    full_path = os.path.join(self.task.path, file)
                    if os.path.isfile(full_path):
                        os.remove(full_path)
                        print(f"已删除缓存文件: {full_path}")
        except Exception as e:
            print(f"清理临时文件失败: {str(e)}")
